home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug202 / ked.c < prev    next >
Text File  |  1979-12-31  |  34KB  |  940 lines

  1. #include <stdio.h>                    /* standard library header */
  2. #include <ctype.h>
  3. #include <ked.h>                            /* globals for editor */
  4.  
  5.  
  6. main(argc,argv)
  7. int argc;                         /* number of arguments for main */
  8. char **argv;                                        /* arg vector */
  9. {
  10.            int i;                             /* next instruction */
  11.            int stop;                        /* boolean to end pgm */
  12.            char nextcomm[MAXLINE];       /* buffer for next instr */
  13.            char *malloc();                    /* allocate function */
  14.            
  15.            stop = 0;                        /* not end of session */ 
  16.            insert = 0;                         /* not insert mode */
  17.            first = last = 0;        /* no entries in symbol table */
  18.            tempend = NULL;                  /* last node inserted */
  19.            temp = NULL;                /* last instr in construct */
  20.  
  21.            if (argc < 3)               /* check for two filenames */
  22.                printf("MISSING FILENAME(S)\n");
  23.            else { 
  24.               initinstr();       /* initialize arrays of commands */
  25.               if ((fptr1 = fopen(argv[1],"r")) == NULL) {
  26.                   p = (struct tnode *)malloc(24); /* create first node */
  27.                   pr = NULL;
  28.                   tree(6,0,5,1,1,0,1,0);
  29.                   endof = pr = curr = root = p;        
  30.                   p = root->sub = (struct tnode *)malloc(24);
  31.                   printf("TYPE MN TO SEE MENU \n");
  32.                   print(root,stdout);
  33.                   prompt("  ",3,"",12,0);
  34.                } else {                            /* if old file */
  35.                     createtree();           /* read in parse tree */
  36.                     curr = root;
  37.                     reply(20);   
  38.                  }
  39.                while (!stop) {
  40.                    i = readin(nextcomm);  /* get the next command */
  41.                    stop = reply(i,argv); /* make correct response */
  42.                }
  43.           }
  44.                   
  45. }
  46.  
  47.  
  48.  
  49. int atoi(n)
  50. char *n;
  51. {
  52.           int val;
  53.           char c;
  54.           int sign;
  55.           val = 0;
  56.           sign = 1;
  57.           while ((c = *n) == '/t' || c== ' ') ++n;
  58.           if (c == '-') {sign = -1; n++;}
  59.           while ( isdigit(c = *n++)) val = val * 10 + c - '0';
  60.           return sign*val;
  61. }
  62.  
  63.  
  64.  
  65. initinstr()    /* initialize arrays of commands */
  66. {
  67.           int i;
  68.           char *malloc();
  69.  
  70. /* allocate space for array entries */
  71. for (i = 0; i < MAXCOMM; i++)   
  72.      comm[i] = malloc(4);
  73. for (i = 0; i < MAXTEST; i++)
  74.      test[i] = malloc(2);
  75. for (i = 0; i < MAXNAME; i++)
  76.      iname[i] = malloc(10);  
  77.  
  78. /* initialize editor commands */
  79. comm[0] = "m";            comm[1] = "tl";
  80. comm[2] = "pi";           comm[3] = "pu";
  81. comm[4] = "to";           comm[5] = "b";
  82. comm[6] = "bepg";         comm[7] = "bx";
  83. comm[8] = "nd";           comm[9] = "ndx";
  84. comm[10] = "ndc";         comm[11] = "if";
  85. comm[12] = "th";          comm[13] = "el";
  86. comm[14] = "it";          comm[15] = "wh";
  87. comm[16] = "df";          comm[17] = "n";
  88. comm[18] = "n-";          comm[19] = "d";
  89. comm[20] = "p";           comm[21] = "i";
  90. comm[22] = "t";           comm[23] = "s";
  91. comm[24] = "q";           comm[25] = "mn";
  92. comm[26] = "n--";         comm[27] = "l";
  93. comm[28] = "nc";          comm[29] = "c";
  94.  
  95.  
  96. /* initialize booleans for Karel's programs */
  97. test[0] = "n";            test[1] = "nn";
  98. test[2] = "s";            test[3] = "ns";
  99. test[4] = "e";            test[5] = "ne";
  100. test[6] = "w";            test[7] = "nw";
  101. test[8] = "c";            test[9] = "nc";
  102. test[10] = "b";           test[11] = "nb";
  103. test[12] = "f";           test[13] = "nf";
  104. test[14] = "l";           test[15] = "nl";
  105. test[16] = "r";           test[17] = "nr";
  106. test[18] = "mn";
  107.  
  108. /* initialize commands for Karel's programs */
  109. iname[0] = "move";        iname[1] = "turnleft";
  110. iname[2] = "pickbeeper";  iname[3] = "putbeeper";
  111. iname[4] = "turnoff";     iname[5] = "begin";
  112. iname[6] = "end";         iname[7] = "if";
  113. iname[8] = "then";        iname[9] = "else";
  114. iname[10] = "iterate";    iname[11] = "while";
  115.  
  116. }
  117.  
  118.  
  119. reply(i,argv)         /* call proper function to handle input */
  120. int i;
  121. char **argv;
  122. {
  123.           int d,valid;
  124.           struct tnode *advance();    
  125.     
  126.           if (i < 0) {                  /* user-defined instr */
  127.               i = -i - 1;         /* converted to distinguish */
  128.               defindst(i);             /* from other commands */
  129.               return 0;
  130.           }
  131.           else {
  132.              switch(i) {
  133.              case 0:      /* move */
  134.              case 1:      /* turnleft */
  135.              case 2:      /* pickbeeper */
  136.              case 3:      /* putbeeper */
  137.              case 4:      /* turnoff */
  138.                 commandst(i);         
  139.                 return 0;
  140.              case 5:      /* BEGIN */
  141.                 compoundst(i);
  142.                 return 0;
  143.              case 7:      /* BEGINNING-OF-EXECUTION */
  144.                 if (insert)
  145.                     printf("COMMAND CAN'T BE INSERTED\n?"); 
  146.                 else execst(i);
  147.                 return 0;
  148.              case 8:      /* END */
  149.                 if (pr->instr == THEN) 
  150.                    endcons();
  151.                 if (insert && insertnode->instr == ND &&
  152.                     insertnode->del != NEWINSTR &&
  153.                    (pr->indent - 1) == (insertnode->indent))
  154.                    printf("END NOT REQUIRED\n?");
  155.                 else {
  156.                    valid = endst(i);
  157.                    if (valid) {
  158.                       endcons();
  159.                       prompt("",3,"",12,i);
  160.                    }
  161.                 }
  162.                 return 0;
  163.              case 9:      /* END-OF-EXECUTION */
  164.                 if (insert)
  165.                     printf("COMMAND CAN'T BE INSERTED\n?");
  166.                 else {
  167.                    if (pr->instr == THEN)  /* automatically end */
  168.                        endcons();                /* THEN and BX */
  169.                    if (pr->indent == 2)
  170.                        endcons();
  171.                    exendst(i);
  172.                 } 
  173.                 return 0;
  174.              case 10:      /* end construct */
  175.                 if (pr->comp == 3)   /* compound statement */
  176.                     printf("END REQUIRED\n");
  177.                 else endcons();
  178.                 prompt("",3,"",12,i);    
  179.                 return 0;
  180.              case 11:      /* IF */
  181.                 ifst(i);
  182.                 return 0;
  183.              case 13:      /* ELSE */
  184.                 elst(i);
  185.                 return 0;
  186.              case 14:      /* ITERATE */
  187.                 iterst(i);
  188.                 return 0;
  189.              case 15:      /* WHILE */
  190.                 whilst(i);
  191.                 return 0;
  192.              case 16:      /* DEFINE-NEW-INSTRUCTION */
  193.                 defst(i);
  194.                 return 0;
  195.              case 17:      /* advance pointer */
  196.                 endinsert();
  197.                 if (!insert) 
  198.                     if (curr == endof)
  199.                         printf("END OF FILE\n");
  200.                     else {
  201.                        curr = advance(curr);
  202.                        print(curr,stdout);
  203.                     } 
  204.                 printf("?");
  205.                 return 0;
  206.              case 18:      /* reverse pointer */
  207.                 endinsert();
  208.                 if (!insert) {
  209.                     if (curr->prev != NULL)
  210.                         curr = curr->prev;
  211.                     print(curr,stdout);
  212.                 }
  213.                 printf("?");
  214.                 return 0;
  215.              case 19:      /* delete */
  216.                 endinsert();
  217.                 if (!insert) 
  218.                     delete();
  219.                 printf("?");
  220.                 return 0;
  221.              case 20:      /* print 20 lines */
  222.                 endinsert();
  223.                 if (!insert) {
  224.                     print(curr,stdout);
  225.                     for (i = 0; i < 20; i++) {
  226.                          if (curr == endof) {
  227.                              printf("END OF FILE\n");
  228.                              break;
  229.                         } else {
  230.                              curr = advance(curr);
  231.                              print(curr,stdout);
  232.                           }
  233.                      }  
  234.                 }
  235.                 printf("?");
  236.                 return 0;
  237.              case 21:      /* insert */
  238.                 if (insert)
  239.                     printf("ALREADY IN INSERT MODE\n");
  240.                 else if (p != pr)       /* NDX not added */
  241.                          printf("INSERT ONLY AFTER END PGM\n");
  242.                      else if ((curr->indent > 2 && curr->instr !=ND) ||
  243.                               (curr->instr == BEG) ||
  244.                               (d = curr->del) == TEST || d == POSINT || 
  245.                               (d == NEWINSTR && curr->prev->instr == DEF))
  246.                               printf("CAN'T INSERT INSIDE CONSTRUCT\n");
  247.                           else insertinstr();  
  248.                 printf("?");
  249.                 return 0;
  250.              case 22:      /* go to top of pgm  */
  251.                 endinsert();
  252.                 if (!insert) {
  253.                     curr = root;  
  254.                     print(curr,stdout);
  255.                 } 
  256.                 printf("?");
  257.                 return 0;
  258.              case 23:      /* save file */
  259.                 endinsert();
  260.                 if (!insert) {
  261.                     if (p != pr)   /* NDX not added */
  262.                         printf("PLEASE END PROGRAM \n");
  263.                     else savetree(root,argv);
  264.                 }
  265.                 printf("?");
  266.                 return 0;
  267.              case 24:      /* quit edit program */
  268.                 endinsert();
  269.                 if (!insert) {
  270.                     printf("HAS PROGRAM BEEN SAVED? (Y/N)\n");
  271.                     if ((i = upper(getchar())) == 'Y') 
  272.                          return 1;
  273.                     else {
  274.                        printf("\n EXIT EDITOR ANYWAY? (Y/N)\n");
  275.                        if ((i = upper(getchar())) == 'Y') 
  276.                           return 1;
  277.                     }
  278.                 }
  279.                 printf("\n?");
  280.                 return 0;
  281.              case 25:      /* output menu */
  282.                 menu();
  283.                 printf("?");
  284.                 return 0;
  285.              case 26:      /* go back 10 lines */
  286.                 endinsert();
  287.                 if (!insert) {
  288.                     for (i = 0; i < 10; i++) 
  289.                          if (curr->prev != NULL)
  290.                              curr = curr->prev;
  291.                          print(curr,stdout);
  292.                 }
  293.                 printf("?");
  294.                 return 0;
  295.              case 27:      /* list entire pgm */
  296.                 endinsert();
  297.                 if (!insert) {
  298.                     print(curr,stdout);
  299.                     while (curr != endof) {
  300.                         curr = advance(curr);
  301.                         print(curr,stdout);
  302.                     } 
  303.                     printf("END OF FILE\n");
  304.                 }
  305.                 printf("?");
  306.                 return 0;
  307.              case 28:      /* advance to next construct */
  308.                 endinsert();
  309.                 if (!insert) {
  310.                    if (curr != endof)
  311.                       while ((curr = advance(curr))->cons != 1)
  312.                           if (curr == endof)
  313.                              break;
  314.                    print(curr,stdout);
  315.                 }
  316.                 printf("?");
  317.                 return 0;
  318.              case 29:     /* print current line */
  319.                 endinsert();
  320.                 if (!insert)
  321.                    print(curr,stdout);
  322.                 return 0; 
  323.             }
  324.         }
  325. }
  326.  
  327.  
  328. defindst(i)                 /* user-defined instruction entered */
  329. int i;
  330. {
  331.          int j,in,d,fn,fs,b,t,l,*valid;
  332.          struct tnode *allocp();
  333.  
  334.          in = checkin(&valid);             /* correct location? */
  335.          b = checkcomp(&valid);          /* compound statement? */
  336.          if (valid) {
  337.              j = 0;                            
  338.              while (new[i].loc[j] != NULL)      /* find loc for */
  339.                 if (++j == 15) {           /* next use of instr */
  340.                    printf("MAXIMUM NUMBER OF USES OF "); 
  341.                    printf("DEFINITION EXCEEDED\n?");
  342.                    return;
  343.                 }
  344.              new[i].loc[j] = p;
  345.              new[i].loc[++j] = NULL;
  346.              d = 4;                      /* line may be deleted */
  347.              fn = 0;                   /* any instr may be next */
  348.              fs = 4;                      /* no component instr */
  349.              t = 0;            /* not start or end of construct */
  350.              l = pr->lastin;        /* last valid sym tab entry */    
  351.              tree(i,in,d,fn,fs,b,t,l);
  352.              p = p->next = allocp();
  353.              print(curr,stdout);
  354.              prompt("",3,"",12,0); 
  355.           }
  356. }
  357.  
  358.  
  359. commandst(i)    /* move, turnleft, pickbeeper, putbeeper, turnoff */
  360. int i;
  361. {
  362.           int in,d,fn,fs,b,t,l,*valid;
  363.           struct tnode *allocp();
  364.  
  365.           in = checkin(&valid);              /* correct location? */
  366.           b = checkcomp(&valid);           /* compound statement? */
  367.           if (valid) {
  368.               d = 1;                       /* line may be deleted */
  369.               fn = 0;                    /* any instr may be next */
  370.               fs = 4;                       /* no component instr */    
  371.               t = 0;             /* not start or end of construct */
  372.               l = pr->lastin;         /* last valid sym tab entry */
  373.               tree(i,in,d,fn,fs,b,t,l);    
  374.               p = p->next = allocp();
  375.               print(curr,stdout);
  376.               prompt("",3,"",12,0);
  377.           }
  378. }
  379.  
  380.  
  381. compoundst(i)                                    /* BEGIN entered */
  382. int i;
  383. {
  384.           int in,d,fn,fs,b,t,l;
  385.           struct tnode *allocp();
  386.  
  387.           switch (pr->comp) {
  388.           case 1:                          /* valid loc for begin */
  389.              in = pr->indent + 1;           /* for pretty printer */
  390.              d = 0;           /* entire construct must be deleted */
  391.              fn = 4;                   /* no valid next construct */
  392.              fs = 0;                      /* any instr may follow */ 
  393.              b = 3;                         /* compound statement */
  394.              t = 0;              /* not start or end of construct */
  395.              l = pr->lastin;          /* last valid sym tab entry */
  396.              tree(i,in,d,fn,fs,b,t,l);
  397.              p = p->sub = allocp();
  398.              print(curr,stdout);
  399.              prompt("  ",3,"",12,0);        
  400.              break;
  401.          case 0:                       /* incorrect loc for BEGIN */
  402.          case 2:
  403.          case 3:                    
  404.             printf("BAD LOCATION FOR BEGIN. TYPE MN TO SEE MENU.\n?");
  405.          }
  406. }
  407.  
  408.  
  409. execst(i)                       /* BEGINNING-OF-EXECUTION entered */
  410. int i;
  411. {
  412.           int in,d,fn,fs,b,t,l;
  413.           struct tnode *allocp();
  414.  
  415.           if (pr->nfollow != 1) {
  416.              printf("BAD LOCATION FOR BEGINNING-OF-EXECUTION. ");
  417.              printf("TYPE MN TO SEE MENU.\n?");
  418.           }  else {
  419.                 in = 1;                     /* for pretty printer */
  420.                 d = 5;              /* construct can't be deleted */
  421.                 fn = 3;     /* no valid next construct except NDX */
  422.                 fs = 0;                   /* any instr may follow */
  423.                 b = 0;                /* not a compound statement */
  424.                 t = 1;                      /* start of construct */
  425.                 l = 15;               /* use any instr in sym tab */
  426.                 tree(i,in,d,fn,fs,b,t,l);
  427.                 p = p->sub = allocp();
  428.                 print(curr,stdout);
  429.                 prompt("  ",3,"",12,0);
  430.              }
  431. }
  432.  
  433.  
  434. endst(i)                                           /* END entered */
  435. int i;
  436. {
  437.           int in,d,fn,fs,b,t,l,valid;
  438.           struct tnode *allocp();
  439.  
  440.           if (pr->comp != 3) {
  441.               printf("STRUCTURE NOT A COMPOUND STATEMENT\n?");
  442.               valid = 0;
  443.           } else {
  444.                 valid = 1;
  445.                 in = pr->indent - 1;         /* for pretty printer */
  446.                 d = 0;         /* entire construct must be deleted */
  447.                 fn = fs = 4;                 /* no valid followers */
  448.                 b = 0;          /* not start of compound statement */
  449.                 t = 2;                         /* end of construct */
  450.                 l = pr->lastin;        /* last valid sym tab entry */
  451.                 tree(i,in,d,fn,fs,b,t,l);
  452.                 p = p->next = allocp();
  453.                 print(curr,stdout);
  454.              }
  455.           return valid;
  456. }
  457.  
  458.  
  459. exendst(i)                             /* END-OF-EXECUTION entered */
  460. int i;
  461. {
  462.           int in,d,fn,fs,b,t,l;
  463.  
  464.           if (pr->nfollow != 3)
  465.              printf("BAD LOCATION FOR END PGM. TYPE MN TO SEE MENU.\n?");
  466.           else {
  467.              in = 1;                         /* for pretty printer */
  468.              d = 5;                  /* construct can't be deleted */
  469.              fn = fs = 4;                    /* no valid followers */
  470.              b = 0;             /* not start of compound statement */
  471.              t = 2;                            /* end of construct */
  472.              l = pr->lastin;           /* last valid sym tab entry */
  473.              tree(i,in,d,fn,fs,b,t,l);
  474.              pr = curr = p;
  475.              print(p,stdout);
  476.              printf("?");
  477.           }
  478. }   
  479.  
  480.  
  481. ifst(i)                                              /* IF entered */
  482. int i;
  483. {
  484.           int j,in,d,fn,fs,b,t,l,*valid,c;
  485.           struct tnode *allocp();
  486.  
  487.           in = checkin(&valid);               /* correct location? */
  488.           b = checkcomp(&valid);            /* compound statement? */
  489.           if (valid) {
  490.               d = 0;           /* entire construct must be deleted */
  491.               fn = 0;           /* any instr may be next construct */
  492.               fs = 2;                      /* only test may follow */
  493.               t = 1;                         /* start of construct */
  494.               l = pr->lastin;          /* last valid sym tab entry */
  495.               tree(i,in,d,fn,fs,b,t,l);
  496.               p = p->sub = allocp();
  497.               do {
  498.                for (j = 0; j < in; j++)
  499.                    printf("  ");
  500.                prompt("IF ",1," ",6,0);
  501.                c = testin();                           /* get test */
  502.                if (c == MENU) 
  503.                    menu();
  504.               } while (c == 18); 
  505.               print(pr->prev,stdout);
  506.               print(pr,stdout);
  507.               thenin();                                /* add THEN */
  508.               print(pr,stdout); 
  509.               prompt("  ",3,"",12,0);
  510.           }
  511. }
  512.  
  513.  
  514. thenin()                                     /* store THEN in tree */
  515. {
  516.           int i,in,d,fn,fs,b,t,l;
  517.           struct tnode *allocp();
  518.  
  519.           i = THEN;
  520.           in = pr->prev->indent + 1;         /* for pretty printer */
  521.           d = 0;               /* entire construct must be deleted */
  522.           fn = 2;               /* only ELSE may be next construct */
  523.           fs = 0;                   /* any valid instr may follow  */
  524.           b = 1;                 /* may precede compound statement */
  525.           t = 1;                             /* start of construct */
  526.           l = pr->lastin;              /* last valid sym tab entry */
  527.           tree(i,in,d,fn,fs,b,t,l);
  528.           p = p->sub = allocp();
  529. }
  530.  
  531.  
  532. elst(i)                                            /* ELSE entered */
  533. int i;
  534. {
  535.          int in,d,fn,fs,b,t,l,*valid;
  536.          struct tnode *allocp();
  537.  
  538.          if (pr->nfollow != 2)
  539.              printf("ELSE NOT PAIRED WITH THEN\n?");
  540.          else {
  541.             i = ELS;
  542.             in = pr->indent;                 /* for pretty printer */
  543.             d = 0;             /* entire construct must be deleted */
  544.             fn = 4;                     /* no valid next construct */
  545.             fs = 0;                  /* any valid instr may follow */
  546.             b = 1;               /* may precede compound statement */
  547.             t = 1;                           /* start of construct */
  548.             l = pr->lastin;            /* last valid sym tab entry */
  549.             tree(i,in,d,fn,fs,b,t,l);
  550.             p = p->sub = allocp();
  551.             print(curr,stdout);
  552.             prompt("  ",3,"",12,0);
  553.         }
  554. }
  555.  
  556.  
  557. iterst(i)                                       /* ITERATE entered */
  558. int i;
  559. {
  560.           int j,in,d,fn,fs,b,t,l,*valid;
  561.           struct tnode *allocp();
  562.  
  563.           in = checkin(&valid);               /* correct location? */
  564.           b = checkcomp(&valid);            /* compound statement? */
  565.           if (valid) {
  566.               d = 0;           /* entire construct must be deleted */
  567.               fn = 0;     /* any valid instr may be next construct */ 
  568.               fs = 2;                   /* only pos int may follow */
  569.               t = 1;                         /* start of construct */
  570.               l = pr->lastin;          /* last valid sym tab entry */
  571.               tree(i,in,d,fn,fs,b,t,l);
  572.               p = p->sub = allocp();
  573.               for (j = 0; j < in; j++)
  574.                  printf("  "); 
  575.               prompt("ITERATE ",2," TIMES",22,0);
  576.               intin();                              /* get pos int */
  577.               printf("\n");
  578.               print(pr->prev,stdout);
  579.               print(pr,stdout);
  580.               prompt("  ",3,"",12,0);
  581.          }
  582. }
  583.  
  584.  
  585. whilst(i)                                         /* WHILE entered */
  586. int i;
  587. {
  588.           int j,in,d,fn,fs,b,t,l,*valid,c;
  589.           struct tnode *allocp();
  590.  
  591.           in = checkin(&valid);               /* correct location? */
  592.           b = checkcomp(&valid);            /* compound statement? */
  593.           if (valid) {
  594.               d = 0;           /* entire construct must be deleted */
  595.               fn = 0;     /* any valid instr may be next construct */
  596.               fs = 2;                      /* only test may follow */
  597.               t = 1;                         /* start of construct */
  598.               l = pr->lastin;          /* last valid sym tab entry */
  599.               tree(i,in,d,fn,fs,b,t,l);
  600.               p = p->sub = allocp();
  601.               do {
  602.                for (j = 0; j < in; j++)
  603.                   printf("  ");
  604.                prompt ("WHILE ",1," DO",8,0);
  605.                c = testin();                           /* get test */
  606.                if (c == MENU) 
  607.                    menu();
  608.               } while (c == MENU);
  609.               print(pr->prev,stdout);
  610.               print(pr,stdout);  
  611.               prompt("  ",3,"",12,0);
  612.           }
  613. }    
  614.          
  615.                            
  616.                       
  617.                                                                                 
  618.                  
  619. defst(i)                          /* DEFINE-NEW-INSTRUCTION entered */
  620. int i;
  621. {
  622.           int in,d,fn,fs,b,t,l;
  623.           struct tnode *allocp();
  624.  
  625.           if (pr->nfollow != 1)
  626.              printf("BAD LOCATION FOR DEFINITION. TYPE MN TO SEE MENU.\n?");
  627.           else if (last == 14)
  628.                   printf("MAXIMUM NUMBER OF DEFINITIONS EXCEEDED.\n?");
  629.           else {
  630.              in = 1;                          /* for pretty printer */
  631.              d = 0;             /* entire construct must be deleted */
  632.              fn = 1;        /* only DEF or BX may be next construct */
  633.              fs = 2;                    /* only new name may follow */ 
  634.              b = 0;             /* won't precede compound statement */
  635.              t = 1;                           /* start of construct */
  636.              if (pr->instr == DEF) 
  637.                  l = new[pr->lastin].nextin;
  638.              else l = pr->lastin;       /* last valid sym tab entry */
  639.              tree(i,in,d,fn,fs,b,t,l);
  640.              p = p->sub = allocp(); 
  641.              newin();                               /* get new name */
  642.              print(pr->prev,stdout);
  643.              print(pr,stdout);
  644.              compoundst(5);                            /* add BEGIN */
  645.           }
  646. }
  647.  
  648.  
  649. testin()                                      /* store test in tree */
  650. {
  651.           int i,in,d,fn,fs,b,t,l;
  652.           struct tnode *allocp();
  653.  
  654.           i = getest();
  655.           if (i != MENU) {
  656.               in = pr->indent;                /* for pretty printer */
  657.               d = 2;               /* no deletion, replacement only */
  658.               fn = 4;                          /* no next construct */
  659.               fs = 0;                       /* any instr may follow */
  660.               b = 1;              /* may precede compound statement */
  661.               t = 0;               /* not start or end of construct */
  662.               l = pr->lastin;           /* last valid sym tab entry */
  663.               tree(i,in,d,fn,fs,b,t,l);
  664.               p = p->sub = allocp();
  665.           }
  666.           return i;
  667. }
  668.  
  669.  
  670. getest()            /* get valid test */
  671. {
  672.           char w[MAXLINE];
  673.           int m;
  674.  
  675.           do {
  676.             inputs(w);   
  677.             if ((m = match(w,test,MAXTEST)) == NOMATCH)
  678.                printf("INVALID TEST. TYPE MN TO SEE MENU.\n?");
  679.           } while (m == NOMATCH);
  680.           return m;
  681. }
  682.  
  683.  
  684. intin()                              /* store positive number in tree */
  685. {
  686.           int i,in,d,fn,fs,b,t,l;
  687.           struct tnode *allocp();
  688.  
  689.           i = getint();
  690.           in = pr->indent;                      /* for pretty printer */
  691.           d = 3;                  /* may not be deleted, replace only */
  692.           fn = 4;                          /* no valid next construct */
  693.           fs = 0;                             /* any instr may follow */
  694.           b = 1;                    /* may precede compound statement */
  695.           t = 0;                     /* not start or end of construct */
  696.           l = pr->lastin;                 /* last valid sym tab entry */
  697.           tree(i,in,d,fn,fs,b,t,l);
  698.           p = p->sub = allocp();
  699. }
  700.  
  701.  
  702. getint()                                       /* get positive number */
  703.           char s[3];
  704.           int i,num;
  705.    
  706.           for (i = 0; (s[i] = getchar()) != ' '
  707.                                  && s[i] != '\n'; ++i);
  708.           s[i] = '\0';                              /* read in string */
  709.           num = atoi(s);                    /* and convert to integer */
  710.           return num;
  711. }
  712.  
  713.  
  714. newin()                                     /* store new name in tree */
  715. {
  716.           int i,in,d,fn,fs,b,t,l;
  717.           struct tnode *allocp();
  718.  
  719.           i = last;                  /* next location in symbol table */
  720.           prompt("  DEFINE-NEW-INSTRUCTION ",4," AS",12,0);
  721.           getnew(i);
  722.           putintable(i);
  723.           in = pr->indent;                      /* for pretty printer */
  724.           d = 4;                  /* may not be deleted, replace only */
  725.           fn = 4;                          /* no valid next construct */
  726.           fs = 0;                     /* any defined instr may follow */
  727.           b = 1;                    /* may precede compound statement */
  728.           t = 0;                     /* not start or end of construct */
  729.           l = last;                       /* last valid sym tab entry */
  730.           tree(i,in,d,fn,fs,b,t,l);
  731.           p = p->sub = allocp();
  732. }
  733.  
  734.  
  735. getnew(i)                /* get unique new name */
  736. int i;
  737. {
  738.           int c,j,m;
  739.  
  740.           do {
  741.             if (inputs(new[i].defname) != ERROR &&
  742.                 new[i].defname[0] >= 'a' &&
  743.                 new[i].defname[0] <= 'z') {
  744.               m = match(new[i].defname,comm,MAXCOMM);
  745.               if (m == NOMATCH)
  746.                 for (j = 0; j < MAXNAME; j++)
  747.                   if ((c = strcomp(new[i].defname,iname[j])) == 0)
  748.                     m = 1;     
  749.               if (m == NOMATCH && last != first) 
  750.                 for (j = first; j != i; j = new[j].nextin)
  751.                   if ((c = strcomp(new[i].defname,new[j].defname)) == 0)
  752.                     m = 1;
  753.               if (m != NOMATCH)
  754.                 printf("\nNEW NAME MUST BE UNIQUE\n?");
  755.             } else {
  756.                  printf("\nINVALID CHARACTERS IN NEW NAME\n?");
  757.                  m = 1;
  758.               }                
  759.           } while (m != NOMATCH);
  760.           new[i].loc[0] = NULL;
  761. }
  762.  
  763.  
  764.  
  765. print(ptr,fptr)                     /* pretty printer */
  766. struct tnode *ptr;
  767. FILE *fptr;
  768. {
  769.           int d,i;
  770.  
  771.           d = ptr->del;
  772.           if (d == TEST || d == POSINT || d == NEWINSTR)
  773.               switch(ptr->prev->instr) {
  774.               case 11:             /* instr is an if test */
  775.                  printest(ptr,fptr);
  776.                  fprintf(fptr,"\n");
  777.                  return;
  778.               case 14:             /* instr is a pos num */
  779.                  fprintf(fptr,"%2d TIMES\n", ptr->instr);
  780.                  return;
  781.               case 15:             /* instr is a while test */
  782.                  printest(ptr,fptr);
  783.                  fprintf(fptr," DO\n");
  784.                  return;
  785.               case 16:             /* instr is a new name */
  786.                  fprintf(fptr,"%s AS\n",new[ptr->instr].defname);
  787.                  return;
  788.               }    
  789.           
  790.           for (i = 0; i < ptr->indent; i++)
  791.                fprintf(fptr,"  ");  /* indent line */
  792.  
  793.           if (d == NEWINSTR) {
  794.              fprintf(fptr,"%s",new[ptr->instr].defname);
  795.              endline(ptr,fptr);
  796.              return;
  797.           }
  798.          
  799.           switch(ptr->instr) {
  800.           case 0:
  801.              fprintf(fptr,"move");
  802.              endline(ptr,fptr);
  803.              break;
  804.           case 1:
  805.              fprintf(fptr,"turnleft");
  806.              endline(ptr,fptr);
  807.              break;
  808.           case 2:
  809.              fprintf(fptr,"pickbeeper");
  810.              endline(ptr,fptr);
  811.              break;
  812.           case 3:
  813.              fprintf(fptr,"putbeeper");
  814.              endline(ptr,fptr);
  815.              break;
  816.           case 4:
  817.              fprintf(fptr,"turnoff");
  818.              endline(ptr,fptr);
  819.              break;
  820.           case 8:
  821.              fprintf(fptr,"END");
  822.              endline(ptr,fptr);
  823.              break;
  824.           case 5:
  825.              fprintf(fptr,"BEGIN\n"); 
  826.              break;
  827.           case 6:
  828.              fprintf(fptr,"BEGINNING-OF-PROGRAM\n");
  829.              break;
  830.           case 7:
  831.              fprintf(fptr,"\n  BEGINNING-OF-EXECUTION\n");
  832.              break;
  833.           case 9:
  834.              fprintf(fptr,"END-OF-EXECUTION\n");
  835.              fprintf(fptr,"END-OF-PROGRAM\n");
  836.              break;
  837.           case 11:
  838.              fprintf(fptr,"IF ");
  839.              break;
  840.           case 12:
  841.              fprintf(fptr,"THEN\n");
  842.              break;
  843.           case 13:
  844.              fprintf(fptr,"ELSE\n");
  845.              break;
  846.           case 14:
  847.              fprintf(fptr,"ITERATE ");
  848.              break;
  849.           case 15:
  850.              fprintf(fptr,"WHILE ");
  851.              break;
  852.           case 16:
  853.              fprintf(fptr,"\n  DEFINE-NEW-INSTRUCTION ");
  854.              break;
  855.           }
  856. }
  857.  
  858.  
  859.  
  860. endline(ptr,fptr)             /* add ; if required and start newline */
  861. struct tnode *ptr;
  862. FILE *fptr;
  863. {
  864.           int i;
  865.          
  866.           i = ptr->next->instr;
  867.           if ((i == ND || i == NDX || i == ELS) &&
  868.                ptr->next->del != NEWINSTR)
  869.              fprintf(fptr,"\n");
  870.           else fprintf(fptr,";\n");  
  871. }
  872.  
  873.  
  874. printest(ptr,fptr)     /* print test after IF or WHILE */
  875. struct tnode *ptr;
  876. FILE *fptr; 
  877. {
  878.  
  879.           switch(ptr->instr) {
  880.           case 0:
  881.              fprintf(fptr,"facing-north");
  882.              break;
  883.           case 1:
  884.              fprintf(fptr,"not-facing-north");
  885.              break;
  886.           case 2:
  887.              fprintf(fptr,"facing-south");
  888.              break;
  889.           case 3:
  890.              fprintf(fptr,"not-facing-south");
  891.              break;
  892.           case 4:
  893.              fprintf(fptr,"facing-east");
  894.              break;
  895.           case 5:
  896.              fprintf(fptr,"not-facing-east");
  897.              break;
  898.           case 6:
  899.              fprintf(fptr,"facing-west");
  900.              break; 
  901.           case 7:
  902.              fprintf(fptr,"not-facing-west");
  903.              break;        
  904.           case 8:
  905.              fprintf(fptr,"next-to-a-beeper");
  906.              break;
  907.           case 9:
  908.              fprintf(fptr,"not-next-to-a-beeper");
  909.              break;
  910.           case 10:
  911.              fprintf(fptr,"any-beepers-in-beeper-bag");
  912.              break;
  913.           case 11:
  914.              fprintf(fptr,"no-beepers-in-beeper-bag");
  915.              break;
  916.           case 12:
  917.              fprintf(fptr,"front-is-clear");
  918.              break;
  919.           case 13:
  920.              fprintf(fptr,"front-is-blocked");
  921.              break;
  922.           case 14:
  923.              fprintf(fptr,"left-is-clear");
  924.              break;
  925.           case 15:
  926.              fprintf(fptr,"left-is-blocked");
  927.              break;
  928.           case 16:
  929.              fprintf(fptr,"right-is-clear");
  930.              break;
  931.           case 17:
  932.              fprintf(fptr,"right-is-blocked");
  933.              break;
  934.           case 18:
  935.              menu();
  936.              break;
  937.           }
  938. }
  939.